/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package babydisco.Math.SVD;


import babydisco.Math.Jama.Matrix;
import java.util.ArrayList;

/**
 *
 * @author Florian
 */
public class SVDICA {
     private SVD svd;
     private double sampleFreq;
     private ArrayList<Double> input;
     private static int K = 10; // we only look at the K-most significant colomns in
                                // v of svd
     private static double EPSILON = 0.8; // currently this high because ICA doesnt seem to drop below 0.7something even after 50 iterations
     private double[][] mostSigV, mostSigS, mostSigU, mixM;
     private double[][] icaV, icaU;
     private double[] uF,uM;

     public SVDICA(ArrayList<Double> input, double sampleFreq) {
        this.svd = new SVD(input , sampleFreq);
        this.input = input;
        this.sampleFreq = sampleFreq;
        ICA();
    }

     public double[][] getICAU(){ return icaU;}

     private void ICA(){
         getKMostSignificant();
         

         //get the mixing matrix
          mixM = FastICACustom.mixingMatrix(mostSigV, 50, EPSILON, 10);
         //updateU
         updateU();
         icaU = FastICACustom.fastICA(mostSigU, 50, EPSILON, 10);
         //now pick the 2 best Uf and Um out of icaU's independt components
         //do this by picking picking the two components with 1 peak
         //according to the paper. I assume this becomes obvious if we can actually
         //see the thing
         //this won't happen until later


     }
     private void updateU(){
    
         Matrix u = new Matrix(mostSigU);
         Matrix m = new Matrix(mixM);
         Matrix s = new Matrix(mostSigS);
         
         u = u.times(s.times(m));
         mostSigU = u.getArray();

     }
     private void getKMostSignificant(){

         double[][] tempV = svd.getV().getArray();
         double[][] tempU = svd.getU().getArray();
         double[][] tempS = svd.getSingularMatrix().getArray();
         mostSigV = new double[tempV.length][K];
         mostSigU = new double[tempU.length][K];
         mostSigS = new double[K][Math.max(tempV.length, K)]; // A diagonal matrix of K most significant values
                                                              // Of such a size that Uk *Sk*M will actually be possible

         for(int i = 0; i < tempV.length; i++){
             for(int j = 0; j<K ;j++){
                 mostSigV[i][j] = tempV[i][j];
             }
         }
         for(int i = 0; i <  tempU.length; i++){
             for(int j = 0; j<K;j++){
                 mostSigU[i][j] = tempU[i][j];
             }
         }
         for(int i = 0; i <K; i++){
             for(int j = 0; j< K;j++){
                 mostSigS[i][j] = tempS[i][j];
             }
         }
         


     }
}
